home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / sulogin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  5.3 KB  |  248 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #include <sys/types.h>
  13. #include <signal.h>
  14. #include <stdio.h>
  15. #include "pwd.h"
  16. #include <utmp.h>
  17. #include <fcntl.h>
  18. #ifdef    BSD
  19. #include <strings.h>
  20. #define    strchr    index
  21. #define    strrchr    rindex
  22. #else
  23. #include <string.h>
  24. #include <memory.h>
  25. #endif
  26. #include "config.h"
  27.  
  28. #if defined(BSD) || defined(SUN)
  29. #include <sgtty.h>
  30. #define    USE_SGTTY    1
  31. #endif
  32. #if defined(USG) || defined(SUN4)
  33. #ifdef    _POSIX_SOURCE
  34. #include <termios.h>
  35. #define    USE_TERMIOS    1
  36. #else
  37. #include <termio.h>
  38. #define    USE_TERMIO    1
  39. #endif
  40. #endif
  41.  
  42. #ifdef    USE_SYSLOG
  43. #include <syslog.h>
  44.  
  45. #ifndef    LOG_WARN
  46. #define    LOG_WARN    LOG_WARNING
  47. #endif
  48. #endif
  49.  
  50. #ifndef    lint
  51. static    char    sccsid[] = "@(#)sulogin.c    3.10    23:56:58    3/7/92";
  52. #endif
  53.  
  54. char    name[BUFSIZ];
  55. char    pass[BUFSIZ];
  56. char    home[BUFSIZ];
  57. char    prog[BUFSIZ];
  58. char    mail[BUFSIZ];
  59.  
  60. struct    passwd    pwent;
  61. struct    utmp    utent;
  62.  
  63. #ifdef    USE_SGTTY
  64. struct    sgttyb    termio;
  65. #endif
  66. #ifdef    USE_TERMIO
  67. struct    termio    termio;
  68. #endif
  69. #ifdef    USE_TERMIOS
  70. struct    termios    termio;
  71. #endif
  72.  
  73. #ifndef    MAXENV
  74. #define    MAXENV    64
  75. #endif
  76.  
  77. char    *newenvp[MAXENV];
  78. int    newenvc = 0;
  79. int    maxenv = MAXENV;
  80. extern    char    **environ;
  81. extern    char    *getpass();
  82.  
  83. extern    char    *getdef_str();
  84.  
  85. #ifndef    ALARM
  86. #define    ALARM    60
  87. #endif
  88.  
  89. #ifndef    RETRIES
  90. #define    RETRIES    3
  91. #endif
  92.  
  93. catch (sig)
  94. int    sig;
  95. {
  96.     exit (1);
  97. }
  98.  
  99. /*ARGSUSED*/
  100. int
  101. main (argc, argv, envp)
  102. int    argc;
  103. char    **argv;
  104. char    **envp;
  105. {
  106.     char    *getenv ();
  107.     char    *ttyname ();
  108.     char    *getpass ();
  109.     char    *tz ();
  110.     char    *cp;
  111.  
  112. #ifdef    USE_SGTTY
  113.     ioctl (0, TIOCGETP, &termio);
  114.     termio.sg_flags |= (ECHO|CRMOD);
  115.     termio.sg_flags &= ~(RAW|CBREAK);
  116.     ioctl (0, TIOCSETN, &termio);
  117. #endif
  118. #ifdef    USE_TERMIO
  119.     ioctl (0, TCSETA, &termio);
  120.     termio.c_iflag |= (ICRNL|IXON);
  121.     termio.c_oflag |= (OPOST|ONLCR);
  122.     termio.c_cflag |= (CREAD);
  123.     termio.c_lflag |= (ISIG|ICANON|ECHO|ECHOE|ECHOK);
  124.     ioctl (0, TCSETAF, &termio);
  125. #endif
  126. #ifdef    USE_TERMIOS
  127.     tcgetattr (0, &termio);
  128.     termio.c_iflag |= (ICRNL|IXON);
  129.     termio.c_oflag |= (CREAD);
  130.     termio.c_lflag |= (ECHO|ECHOE|ECHOK|ICANON|ISIG);
  131.     tcsetattr (0, TCSANOW, &termio);
  132. #endif
  133. #ifdef    USE_SYSLOG
  134.     openlog ("sulogin", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  135. #endif
  136.     if (argc > 1) {
  137.         close (0);
  138.         close (1);
  139.         close (2);
  140.  
  141.         if (open (argv[1], O_RDWR) >= 0) {
  142.             dup (0);
  143.             dup (0);
  144.         } else {
  145. #ifdef    USE_SYSLOG
  146.             syslog (LOG_WARN, "cannot open %s\n", argv[1]);
  147. #endif
  148.             exit (1);
  149.         }
  150.     }
  151.     if (access (PWDFILE, 0) == -1) { /* must be a password file! */
  152.         printf ("No password file\n");
  153. #ifdef    USE_SYSLOG
  154.         syslog (LOG_WARN, "No password file\n");
  155. #endif
  156.         exit (1);
  157.     }
  158. #ifndef    DEBUG
  159.     if (getppid () != 1) {        /* parent must be INIT */
  160. #ifdef    USE_SYSLOG
  161.         syslog (LOG_WARN, "Pid == %d, not 1\n", getppid ());
  162. #endif
  163.         exit (1);
  164.     }
  165. #endif
  166.     if (! isatty (0) || ! isatty (1) || ! isatty (2))
  167.         exit (1);        /* must be a terminal */
  168.  
  169.     while (*envp)            /* add inherited environment, */
  170.         addenv (*envp++);    /* some variables change later */
  171.  
  172.     if (cp = getdef_str("ENV_TZ"))
  173.         addenv (*cp == '/' ? tz(cp) : cp);
  174.     if (cp = getdef_str("ENV_HZ"))
  175.         addenv (cp);        /* set the default $HZ, if one */
  176.     (void) strcpy (name, "root");    /* KLUDGE!!! */
  177.  
  178.     signal (SIGALRM, catch);    /* exit if the timer expires */
  179.     alarm (ALARM);            /* only wait so long ... */
  180.  
  181.     while (1) {        /* repeatedly get login/password pairs */
  182.         entry (name, &pwent);    /* get entry from password file */
  183.         if (pwent.pw_name == (char *) 0) {
  184.             printf ("No password entry for 'root'\n");
  185. #ifdef    USE_SYSLOG
  186.             syslog (LOG_WARN, "No password entry for 'root'\n");
  187. #endif
  188.             exit (1);
  189.         }
  190.  
  191.     /*
  192.      * Here we prompt for the root password, or if no password is
  193.      * given we just exit.
  194.      */
  195.  
  196.                     /* get a password for root */
  197.         if (! (cp = getpass ("Type control-d for normal startup,\n\
  198. (or give root password for system maintenance):"))) {
  199. #ifdef    USE_SYSLOG
  200.             syslog (LOG_INFO, "Normal startup\n");
  201. #endif
  202. #ifdef    TELINIT
  203.             execl ("/etc/telinit", "telinit", RUNLEVEL, (char *) 0);
  204. #endif
  205.             exit (0);
  206.         } else
  207.             strcpy (pass, cp);
  208.  
  209.         if (valid (pass, &pwent)) /* check encrypted passwords ... */
  210.             break;        /* ... encrypted passwords matched */
  211.  
  212.         puts ("Login incorrect");
  213. #ifdef    USE_SYSLOG
  214.         syslog (LOG_WARN, "Incorrect root password\n");
  215. #endif
  216.     }
  217.     alarm (0);
  218.     signal (SIGALRM, SIG_DFL);
  219.     environ = newenvp;        /* make new environment active */
  220.  
  221.     puts ("Entering System Maintenance Mode");
  222. #ifdef    USE_SYSLOG
  223.     syslog (LOG_INFO, "System Maintenance Mode\n");
  224. #endif
  225.  
  226.     /*
  227.      * Normally there would be a utmp entry for login to mung on
  228.      * to get the tty name, date, etc. from.  We don't need all that
  229.      * stuff because we won't update the utmp or wtmp files.  BUT!,
  230.      * we do need the tty name so we can set the permissions and
  231.      * ownership.
  232.      */
  233.  
  234.     if (cp = ttyname (0)) {        /* found entry in /dev/ */
  235.         if (strrchr (cp, '/') != (char *) 0)
  236.             strcpy (utent.ut_line, strrchr (cp, '/') + 1);
  237.         else
  238.             strcpy (utent.ut_line, cp);
  239.     }
  240.     if (getenv ("IFS"))        /* don't export user IFS ... */
  241.         addenv ("IFS= \t\n");    /* ... instead, set a safe IFS */
  242.  
  243.     setup (&pwent);            /* set UID, GID, HOME, etc ... */
  244.  
  245.     shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
  246.     /*NOTREACHED*/
  247. }
  248.